import pandas as pd
import numpy as np
from lightgbm import LGBMClassifier
from sklearn.model_selection import GridSearchCV, StratifiedKFold
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report, roc_auc_score
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder
from imblearn.over_sampling import SMOTE
from imblearn.pipeline import Pipeline as ImbPipeline
from category_encoders import TargetEncoder
from utils.data_load import dataload


# ================== 1. 数据加载 ==================
X_train, X_test, y_train, y_test = dataload()

# ================== 2. 自动识别特征类型 ==================
categorical_features = X_train.select_dtypes(include=['object']).columns.tolist()
numerical_features = X_train.select_dtypes(exclude=['object']).columns.tolist()

print(f"分类特征: {categorical_features}")
print(f"数值特征: {numerical_features}")

# ================== 3. 预处理：目标编码 + 缺失值填充 + 标准化 ==================

# 数值特征处理流程
numeric_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='median')),  # 缺失值填充
    ('scaler', StandardScaler())                   # 标准化
])

# 分类特征处理流程（目标编码）
categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='most_frequent')),  # 缺失值填充
    ('target_encoder', TargetEncoder())                    # 目标编码
])

# 合并预处理
preprocessor = ColumnTransformer(
    transformers=[
        ('num', numeric_transformer, numerical_features),
        ('cat', categorical_transformer, categorical_features)
    ])

# ================== 4. LightGBM 模型 ==================
lgbm = LGBMClassifier(
    objective='binary',
    boosting_type='gbdt',
    random_state=42,
    n_jobs=-1
)

# ================== 5. 建立完整管线（含SMOTE） ==================
model = ImbPipeline(steps=[
    ('preprocessor', preprocessor),
    ('smote', SMOTE(random_state=42)),
    ('classifier', lgbm)
])

# ================== 6. 网格搜索参数 ==================
param_grid = {
    'classifier__num_leaves': [31, 63],
    'classifier__max_depth': [-1, 10, 20],
    'classifier__learning_rate': [0.05, 0.1, 0.2],
    'classifier__n_estimators': [100, 200, 300],
    'classifier__subsample': [0.8, 1.0],
    'classifier__colsample_bytree': [0.8, 1.0]
}

# ================== 7. 网格搜索 + 交叉验证 ==================
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
grid_search = GridSearchCV(
    model,
    param_grid=param_grid,
    scoring='roc_auc',
    cv=cv,
    n_jobs=-1,
    verbose=2
)

grid_search.fit(X_train, y_train)

# ================== 8. 输出最优参数 ==================
print("最佳参数：", grid_search.best_params_)
print("最佳 AUC：", grid_search.best_score_)

# ================== 9. 模型评估 ==================
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)
y_proba = best_model.predict_proba(X_test)[:, 1]

print("\n===== 分类报告 =====")
print(classification_report(y_test, y_pred))

print("测试集AUC：", roc_auc_score(y_test, y_proba))
